/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package player;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;

import javax.media.*;
import javax.media.control.StreamWriterControl;
import javax.media.protocol.FileTypeDescriptor;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class MediaPlayer extends JFrame implements ControllerListener, Runnable {

// Attributs de la classe 
    private JTextField fldAffichageDuree;
    private JTextField fldAffichagePosition;
    private JLabel lbVolume;
    private JButton bPlay = null;
    private JButton bPause = null;
    private JButton bStop = null;
    private JLabel chargementImage;
    private JSlider sSlider;
    private JProgressBar jSlider;
    private JSlider sVolume;
    private javax.media.Player player;
//private String repertoire = "file:Vidéos/"; 
    private String repertoire = "file:C:/";
    private String urlFilm;
    private Time duree;
    private JPanel videoPanel;
    private float t0;
    private float t1;
    private boolean intervalle;
    protected GainControl gain = null;
    boolean running;
    static Thread t;
    
    
    private SocketTCPClient Manager_relay;
    private String manager_ip = "5.39.79.86";
    private String media_ID;

    /**
     * *
     * WMediaPlayer : Constructeur qui permet de créer l'interface graphique *
     *
     *
     * @_nomFichier String : Nom du fichier du film à visualiser * @_t0 float :
     * Temps (en secondes) depuis où l'on veut visualiser la vidéo * S'il est
     * vide, voir depuis le début * @_t1 float : Temps (en secondes) jusqu'où où
     * l'on veut visualiser la vidéo * S'il est vide, voir depuis le début *
     * @_intervalle boolean : Soit on visualise toute la vidéo, soit un
     * intervalle *
     */
    //public MediaPlayer(String _nomFichier, float _t0, float _t1, boolean _intervalle) {
    public MediaPlayer(String _nomFichier, float _t0, float _t1, boolean _intervalle, String ID, String IP_manager) {
    
// Appel du constructeur de JFrame 

        super();

        // Récupérer les paramètres 
        t0 = _t0;
        t1 = _t1;
        intervalle = _intervalle;
        this.media_ID = ID;
        this.manager_ip = IP_manager;

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        
        chargementImage = new JLabel(new ImageIcon (getClass().getResource("wait-loading.gif"))); 
        setSize(490, 250);
        this.add(chargementImage);
        
        
        //Time showLoading = player.getStartLatency();
        //System.out.println(showLoading);
        
            
        
        
        
        
        
        // Vérifier que le nom du fichier passé en paramètre ne soit pas nul 
        // Si c'est en ordre, chargement du film 
        if (_nomFichier != null) {
            fChargerFilm(_nomFichier);
            
        }

        // Evénement lors de la fermeture du player 
        addWindowListener(
                new WindowAdapter() {

                    public void windowClosing(WindowEvent we) {
                        
                        // Desenregistre le serveur
                            Manager_relay = new SocketTCPClient(manager_ip);
                            Manager_relay.delProvider(media_ID, "");
                        
                        // Fermer le player 
                        System.out.println("\nFermeture du player...");
                       
                        if (player != null) {
                            player.close();
                            //player.stop();
                            //t.stop();
                        }
                    }
                });
    }

    /**
     * *
     * fChargerFilm : Cette méthode permet de charger le film passé en paramètre
     * *
     *
     *
     * @_nomFichier String : Nom du fichier du film à visualiser *
     */
    public void fChargerFilm(String _nomFichier) {

// Définir l'URL en fonction du nom du fichier 

        //urlFilm = repertoire + _nomFichier + ".avi";
        //urlFilm = "http://www.solti.fr/Clients/INP/start01.avi";
        urlFilm = _nomFichier;
        
// Création du player 

        try {
            //System.setProperty("http.proxyHost", "proxybc.goss.cat.com");
            //save(); // sauvegarde de la video

            player = Manager.createPlayer(new MediaLocator(urlFilm));
            //player = Manager.createPlayer(new MediaLocator("rtsp://127.0.0.1:8500/test.sdp"));
            player.addControllerListener(this);
            //save(); // sauvegarde de la video            
            // Si la création du player est en ordre, attributs de la fenêtre 
            
            setLocation(400, 200);
            setTitle("Player");
            setVisible(true);
            
            
            
            
            
            
            
            
            
            // Cette fonction permet au player d'acquérir toutes les informations 
            // et toutes les ressources qui lui sont nécessaires sur le média 
            //JOptionPane.showMessageDialog(this,                     "Acquésition des ressources et des informations média en cours. \nPatientez S'il vous plait. : ", "Information", JOptionPane.WARNING_MESSAGE);
            player.realize();
            player.start();
            
            //fGestionTemps(); 

        } catch (Exception error) {

            // Afficher un message d'erreur si nécessaire 
            JOptionPane.showMessageDialog(this,
                    "Erreur lors de la création du player !\nMessage d'erreur : " + error.getMessage(), "Attention", JOptionPane.WARNING_MESSAGE);

            return;
        }
    }

    /**
     * *
     * controllerUpdate : Cette fonction intercepte tous les événements en *
     * provenance du playser (gestionnaire d'événements) *
     *
     *
     * @_event ControllerEvent : Un événement est intervenu sur un des
     * composants *
     */
    public void controllerUpdate(ControllerEvent _event) {

// Donner la durée du film 
        if (_event instanceof DurationUpdateEvent) {
            duree = ((DurationUpdateEvent) _event).getDuration();
        }

        // Créer les composants et les événements 
        if (_event instanceof RealizeCompleteEvent) {
            this.remove(chargementImage);
            // Création des composants 
            bPlay = new JButton(new ImageIcon (getClass().getResource("Play.png")));
            //bPlay = new JButton("Play");

            bPause = new JButton(new ImageIcon (getClass().getResource("Pause.png"))); 
            //bPause = new JButton("Pause");

            bStop = new JButton(new ImageIcon (getClass().getResource("Stop.png"))); 
            //bStop = new JButton("Stop");

            fldAffichageDuree = new JTextField();
            fldAffichagePosition = new JTextField();
            lbVolume = new JLabel("Volume");

            // Récupérer le temps du film pour spécifier la barre de progression 
            // et l'afficher 
            duree = player.getDuration();
            sSlider = new JSlider(JSlider.HORIZONTAL, 0, (int) (duree.getSeconds()), 0);
            jSlider = new JProgressBar(JProgressBar.HORIZONTAL, 0, (int) (duree.getSeconds()));
            sVolume = new JSlider(JSlider.HORIZONTAL, 0, 10, 10);
            System.out.println(duree.getSeconds());

            // Gestionnaire d'événement sur le slider 

            sSlider.addChangeListener(
                    new ChangeListener() {
                        // Lorsque le curseur se déplace 

                        public void stateChanged(ChangeEvent arg0) {
// Déplacer la position du film 
                            float l_tempCourant = sSlider.getValue();
                            player.setMediaTime(new Time(l_tempCourant));
                        }
                    });
            

            // Paramètres de la barre de progression 
            sSlider.setMajorTickSpacing((int) duree.getSeconds() / 10);
            sSlider.setMinorTickSpacing(2);
            //sSlider.setPaintTicks(true);
            sSlider.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));

            // Gestionnaire d'événement sur le slider du volume 

            sVolume.addChangeListener(
                    new ChangeListener() {
                        // Lorsque le curseur se déplace 

                        public void stateChanged(ChangeEvent arg0) {

// Dès que l'utilisateur modifie la position du slider 
// ==> modifier la valeur du volume en conséquence 
// Récupérer la valeur du slider (de 0 à 10) 
                            int l_valeurVolume = sVolume.getValue();

// Le gain est compris entre 0 et 1, donc multiplication par 0.1 
                            gain.setLevel((float) (l_valeurVolume * 0.1));
                        }
                    });

            // Panel regroupant les informations pour le volume 

            JPanel pVolume = new JPanel();
            pVolume.add(lbVolume);
            pVolume.add(sVolume);

            // Panel regroupant les boutons 

            JPanel pBouton = new JPanel(new FlowLayout());
            pBouton.add(bPlay);
            pBouton.add(bPause);
            pBouton.add(bStop);

            // Panel regroupant les afficheurs 
            
            JPanel pAfficheur = new JPanel(new BorderLayout());
            pAfficheur.add(fldAffichageDuree, BorderLayout.NORTH);
            pAfficheur.add(fldAffichagePosition, BorderLayout.CENTER);
            pAfficheur.add(pVolume, BorderLayout.SOUTH);
            
            // Panel regroupant la barre de progression, les boutons et l'afficheur 
            
            JPanel pControle = new JPanel(new BorderLayout());
            pControle.add(sSlider, BorderLayout.NORTH);
            //pControle.add(jSlider, BorderLayout.NORTH);
            //pControle.add(pAfficheur, BorderLayout.CENTER);
            pControle.add(pBouton, BorderLayout.SOUTH);
            
            // Paramètres de l'afficheur 

            fldAffichageDuree.setEditable(false);
            fldAffichagePosition.setEditable(false);
            fldAffichageDuree.setText("Durée du film : " + (float) duree.getSeconds() / 60 + " minutes");

            if (videoPanel == null) {
                // Création du panel 
                videoPanel = new JPanel();
                videoPanel.setLayout(new BorderLayout());
                getContentPane().add(videoPanel, BorderLayout.CENTER);
            } else {
                videoPanel.removeAll();
            }

            // Récupérer le composant contenant l'image provenant du player 
            Component vis = player.getVisualComponent();
            if (vis != null) {
                // Ok donc ajout de l'aspect visuel du média 
                videoPanel.add(vis, BorderLayout.CENTER);
                videoPanel.add(pControle, BorderLayout.SOUTH);
                videoPanel.setVisible(true);
                this.pack();
            }

            // Evénements sur les boutons 
            // Bouton "play" 
            bPlay.addActionListener(
                    new ActionListener() {

                        public void actionPerformed(ActionEvent e) {
                            player.start();
                            // FAIRE QUE LE THREAD CONTINUE 
                        }
                    });

            // Bouton "pause" 
            bPause.addActionListener(
                    new ActionListener() {

                        public void actionPerformed(ActionEvent e) {
                            // METTRE LE THREAD EN PAUSE 
                            try {
                                t.wait();
                            } catch (InterruptedException e1) {
                                e1.printStackTrace();
                            }

                            player.stop();
                            player.deallocate();
                        }
                    });

            // Bouton "stop" 

            bStop.addActionListener(
                    new ActionListener() {

                        public void actionPerformed(ActionEvent e) {
                            player.stop();
                            player.deallocate();
                            // Remettre la vidéo au début 
                            player.setMediaTime(new Time(0));
                            // Remettre à la barre de progression à 0 
                            sSlider.setValue(0);
                            if (player.getTargetState() < javax.media.Player.Started) {
                                player.prefetch();
                            }

                            // ARRETER LE THREAD 
                        }
                    });

            // Placer la vidéo à l'endroit approprié 
            player.setMediaTime(new Time(t0));
            sSlider.setValue((int) t0);
            
            
            
            
        }

        if (_event instanceof PrefetchCompleteEvent) {
            // Récupérer le gain du player 
            gain = (GainControl) player.getControl("javax.media.GainControl");
        }

    }

    /*
    public static void main(String[] args) {

//new test("Issco-35", 0, 0, false); 

        //String chemin = "http://www.solti.fr/Clients/INP/start01.avi";
        String chemin = "file:C:/01.avi";
        t = new Thread(new MediaPlayer(chemin, 0, 0, false));
        t.start();

    }
    
    */


    public void run() {

// Etat du player 

        int state = player.getState();

        while (state != Controller.Started) {
            try {
                t.sleep(100);
                state = player.getState();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        while (t.isAlive()) {

            try {
                Time time = player.getMediaTime();
                state = player.getState();
                double seconds = time.getSeconds();

                if (seconds >= 0.0d) {
                    System.out.println("Time: " + seconds);
                }

                if (state != Controller.Started && state != Controller.Prefetching && state != Controller.Realizing) {
                    running = false;
                }
                t.sleep(1000);

            } catch (Exception e) {
                e.printStackTrace();
            }

        }

    }

    /*
    public void save() throws IOException, NoProcessorException {

        // SAUVEGARDE DU FLUX
        Processor p = Manager.createProcessor(new MediaLocator(urlFilm));

        jmapps.util.StateHelper sh = new jmapps.util.StateHelper(p);
        sh.configure(10000);
        sh.realize(10000);


        //p.configure();
        //p.setContentDescriptor(new FileTypeDescriptor(FileTypeDescriptor.MPEG));
        //p.realize();
        DataSink sink;
        MediaLocator dest = new MediaLocator("file://C:/save.avi"); // destination = repertoire server web

        try {

            sink = Manager.createDataSink(p.getDataOutput(), dest);
            sink.open();

            StreamWriterControl swc = (StreamWriterControl) p.getControl("javax.media.control.StreamWriterControl");
            swc.setStreamSizeLimit(25000000);

            sh.playToEndOfMedia(5000);


            sink.start();
            sh.playToEndOfMedia(5000);
            sh.close();
            sink.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    */
}
